package com.fashion.service.brand;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Service;

import com.fashion.model.NewsColumn;
import com.fashion.model.brand.Brand;
import com.fashion.service.ColumnServiceImpl;

@Service("brandService")
public class BrandService {
	private static final Logger logger = Logger.getLogger(BrandService.class);
	
	@Resource(name = "hibernateTemplate")
	private HibernateTemplate template;
	
	public List<Brand> find(int offset, int limit, String order){
		DetachedCriteria criteria = DetachedCriteria.forClass(Brand.class);
		if(order != null && "".equals(order)){
			criteria.addOrder(Order.asc(order));
		}else{
			criteria.addOrder(Order.desc("priority"));
		}
		return template.findByCriteria(criteria, offset, limit);
	}
	
	public List<Brand> find(NewsColumn industry, NewsColumn district, String firstChar, int offset, int limit){
		DetachedCriteria criteria = DetachedCriteria.forClass(Brand.class);
		if(industry != null){
			criteria = criteria.createAlias("industries", "ind");
			criteria.add(Restrictions.eq("ind.id", industry.getId()));
		}
		if(district != null){
			criteria.add(Restrictions.eq("district.id", district.getId()));
		}
		if(firstChar !=null){
			if("others".equals(firstChar)){
				List<String> list = new ArrayList<String>();
				for(int i = 97; i<=122; i++){
					list.add(String.valueOf((char)i));
				}
				for(String ch : list){
					criteria.add(Restrictions.not(Restrictions.ilike("enTitle", ch, MatchMode.START)));
				}
			}else{
				criteria.add(Restrictions.ilike("enTitle", firstChar, MatchMode.START));
			}
		}
		criteria.addOrder(Order.desc("priority"));
		return template.findByCriteria(criteria, offset, limit);
	}
	
	public int count(NewsColumn industry, NewsColumn district, String firstChar){
		DetachedCriteria criteria = DetachedCriteria.forClass(Brand.class);
		if(industry != null){
			criteria = criteria.createAlias("industries", "ind");
			criteria.add(Restrictions.eq("ind.id", industry.getId()));
		}
		if(district != null){
			criteria.add(Restrictions.eq("district.id", district.getId()));
		}
		if(firstChar !=null){
			if("others".equals(firstChar)){
				List<String> list = new ArrayList<String>();
				for(int i = 97; i<=122; i++){
					list.add(String.valueOf((char)i));
				}
				for(String ch : list){
					criteria.add(Restrictions.not(Restrictions.ilike("enTitle", ch, MatchMode.START)));
				}
			}else{
				criteria.add(Restrictions.ilike("enTitle", firstChar, MatchMode.START));
			}
		}
		criteria.setProjection(Projections.count("id"));
		return ((Integer)template.findByCriteria(criteria).get(0)).intValue();
	}
	
	public List<Brand> findNotStartWithEn(int offset, int limit){
		DetachedCriteria criteria = DetachedCriteria.forClass(Brand.class);

		List<String> list = new ArrayList();
		for(int i = 97; i<=122; i++){
			list.add(String.valueOf((char)i));
		}
		for(String ch : list){
			criteria.add(Restrictions.not(Restrictions.ilike("enTitle", ch, MatchMode.START)));
		}
		criteria.addOrder(Order.desc("priority"));
		criteria.addOrder(Order.asc("enTitle"));
		return template.findByCriteria(criteria, offset, limit);
	}
	
	public List<Brand> findByFirstChar(String first, int offset, int limit){
		DetachedCriteria criteria = DetachedCriteria.forClass(Brand.class);
		criteria.add(Restrictions.ilike("enTitle", first, MatchMode.START));
		criteria.addOrder(Order.desc("priority"));
		criteria.addOrder(Order.asc("enTitle"));
		return template.findByCriteria(criteria, offset, limit);
	}
	
	public List<Brand> findByKeywords(String[] keywords, int offset, int limit){
		DetachedCriteria criteria = DetachedCriteria.forClass(Brand.class);
		Criterion c = Restrictions.ilike("product", keywords[0], MatchMode.ANYWHERE);
		for(int i = 1; i < keywords.length; i++){
			c = Restrictions.or(c, Restrictions.ilike("product", keywords[i], MatchMode.ANYWHERE));
		}
		criteria.add(c);
		criteria.addOrder(Order.desc("priority"));
		criteria.addOrder(Order.asc("enTitle"));
		return template.findByCriteria(criteria, offset, limit);
	}
	
	public long countNotStartWithEn(){
		DetachedCriteria criteria = DetachedCriteria.forClass(Brand.class);

		List<String> list = new ArrayList();
		for(int i = 97; i<=122; i++){
			list.add(String.valueOf((char)i));
		}
		for(String ch : list){
			criteria.add(Restrictions.not(Restrictions.ilike("enTitle", ch, MatchMode.START)));
		}
		criteria.setProjection(Projections.count("id"));
		List result = template.findByCriteria(criteria);
		if(result.size() == 0)
			return 0;
		return ((Integer)template.findByCriteria(criteria).get(0)).intValue();
	}
	
	public long countByFirstChar(String first){
		DetachedCriteria criteria = DetachedCriteria.forClass(Brand.class);
		criteria.add(Restrictions.ilike("enTitle", first, MatchMode.START));
		criteria.setProjection(Projections.count("id"));
		List result = template.findByCriteria(criteria);
		if(result.size() == 0)
			return 0;
		return ((Integer)template.findByCriteria(criteria).get(0)).intValue();
	}
	
	public Brand findById(String id){
		return template.get(Brand.class, id);	
	}
	
	public List<Brand> findByIds(List<String> ids){
		DetachedCriteria criteria = DetachedCriteria.forClass(Brand.class);
		criteria.add(Restrictions.in("id", ids));
		criteria.addOrder(Order.desc("priority"));
		criteria.addOrder(Order.asc("enTitle"));	
		return template.findByCriteria(criteria);
	}
	
	public List<Brand> findByEnTitle(String enTitle, int offset, int limit){
		DetachedCriteria criteria = DetachedCriteria.forClass(Brand.class);
		criteria.add(Restrictions.ilike("enTitle", enTitle, MatchMode.ANYWHERE));
		criteria.addOrder(Order.desc("priority"));
		criteria.addOrder(Order.asc("enTitle"));
		return template.findByCriteria(criteria, offset, limit);
	}
	
	public long countByEnTitle(String enTitle){
		DetachedCriteria criteria = DetachedCriteria.forClass(Brand.class);
		criteria.add(Restrictions.ilike("enTitle", enTitle, MatchMode.ANYWHERE));
		criteria.setProjection(Projections.count("enTitle"));
		List result = template.findByCriteria(criteria);
		if(result.size() == 0)
			return 0;
		return ((Integer)template.findByCriteria(criteria).get(0)).intValue();
	}
	
	public void add(Brand brand){
		String brandId = "";
		String id = brand.getEnTitle().toLowerCase().replace(" ", "");
		Pattern pattern = Pattern.compile("\\w");
		for(int i = 0; i < id.length(); i++){
			String ch = id.substring(i, i+1);
			Matcher matcher = pattern.matcher(ch);
			if(matcher.find()){
				brandId = brandId + ch;
			}
		}		
		brand.setId(brandId);
		template.save(brand);
	}
	
	public void delete(Brand brand){
		template.delete(brand);
	}
	
	public void update(Brand brand){
		template.update(brand);
	}
}